﻿#include "stdafx.h"
#include "mysql_pool.h"
#include <algorithm>
#include <chrono>

mysql_pool& mysql_pool::get_instance()
{
	return _pool;
}

void mysql_pool::setParam(const std::string& conn_str_addr, const std::string& conn_str_user, const std::string& conn_str_password, unsigned short max_size)
{
	pool_size = max_size;
	_conn_str_addr = conn_str_addr;
	_conn_str_user = conn_str_user;
	_conn_str_password = conn_str_password;
}


void mysql_pool::init_connection()
{
	cir_buffer.reset_size(pool_size);

	std::for_each(cir_buffer.begin(), cir_buffer.end(),
		[=](std::shared_ptr<sql::Connection> conn){
			create_connection();
		});
}

mysql_pool::connection_ptr mysql_pool::create_connection()
{

	std::lock_guard<std::mutex> lock(_mutex);
	//std::shared_ptr<mysql> my(new mysql());
	std::shared_ptr<mysql> my(new mysql());
	auto conn = my->connect(_conn_str_addr, _conn_str_user, _conn_str_password);
	
	if (conn)
		cir_buffer.push_back(conn);

	return conn;
}


mysql_pool::connection_ptr mysql_pool::get_connection_ptr()
{
	mysql_pool::connection_ptr conn_ptr;


	auto begin = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());

	while (1)
	{
		std::lock_guard<std::mutex> lock(_mutex);

		if (cir_buffer.size() == 0)
		{
			auto now = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());

			if (now - begin > 10)
			{
				create_connection();
				begin = now;
			}
		}

		conn_ptr = cir_buffer.front();
		cir_buffer.pop_front();

		if (!conn_ptr)
		{
			break;
		}
		else
		{
			create_connection();
		}
	}

	return conn_ptr;
}

void mysql_pool::release_connection(connection_ptr ptrConn)
{
	std::lock_guard<std::mutex> lock(_mutex);
	
	if (ptrConn)
		cir_buffer.push_back(ptrConn);
}